/*
 * eID Test PKI Project.
 * Copyright (C) 2012 FedICT.
 * Copyright (C) 2012 Frank Cornelis.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version
 * 3.0 as published by the Free Software Foundation.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, see 
 * http://www.gnu.org/licenses/.
 */

package be.fedict.eid.pki.console;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.primefaces.context.RequestContext;

import be.fedict.eid.pki.entity.CertificateAuthorityEntity;
import be.fedict.eid.pki.exception.ExistingCertificateAuthorityException;
import be.fedict.eid.pki.exception.InvalidPolicyException;
import be.fedict.eid.pki.exception.InvalidX500NameException;
import be.fedict.eid.pki.model.CertificateAuthorityManagerBean;

@Named
@ConversationScoped
public class CertificateAuthorityController implements Serializable {

	private static final long serialVersionUID = 1L;

	private static final Log LOG = LogFactory
			.getLog(CertificateAuthorityController.class);

	@EJB
	private CertificateAuthorityManagerBean certificateAuthorityManagerBean;

	@Inject
	private Conversation conversation;

	private String name;

	private String subject;

	private Integer keySize;

	private int validity;

	private CertificateAuthorityEntity removeCandidate;

	private String policyOid;

	private String cps;

	private int crlValidity;

	private int crlOverlap;

	private CertificateAuthorityEntity selectedCA;

	private String interSubject;

	private int interValidity;

	private int interSpawnInterval;

	private int interSpawnCount;

	private String interPolicyOid;

	@Produces
	@Named("CertificateAuthorities")
	public List<CertificateAuthorityEntity> initCertificateAuthoritiesList() {
		return this.certificateAuthorityManagerBean.getCertificateAuthorities();
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSubject() {
		return this.subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public Integer getKeySize() {
		return this.keySize;
	}

	public void setKeySize(Integer keySize) {
		this.keySize = keySize;
	}

	public int getValidity() {
		return this.validity;
	}

	public void setValidity(int validity) {
		this.validity = validity;
	}

	public String getPolicyOid() {
		return this.policyOid;
	}

	public void setPolicyOid(String policyOid) {
		this.policyOid = policyOid;
	}

	public String getCps() {
		return this.cps;
	}

	public void setCps(String cps) {
		this.cps = cps;
	}

	public int getCrlValidity() {
		return this.crlValidity;
	}

	public void setCrlValidity(int crlValidity) {
		this.crlValidity = crlValidity;
	}

	public int getCrlOverlap() {
		return this.crlOverlap;
	}

	public void setCrlOverlap(int crlOverlap) {
		this.crlOverlap = crlOverlap;
	}

	public CertificateAuthorityEntity getSelectedCA() {
		return this.selectedCA;
	}

	public String getInterSubject() {
		return this.interSubject;
	}

	public void setInterSubject(String interSubject) {
		this.interSubject = interSubject;
	}

	public int getInterValidity() {
		return this.interValidity;
	}

	public void setInterValidity(int interValidity) {
		this.interValidity = interValidity;
	}

	public int getInterSpawnInterval() {
		return this.interSpawnInterval;
	}

	public void setInterSpawnInterval(int interSpawnInterval) {
		this.interSpawnInterval = interSpawnInterval;
	}

	public int getInterSpawnCount() {
		return this.interSpawnCount;
	}

	public void setInterSpawnCount(int interSpawnCount) {
		this.interSpawnCount = interSpawnCount;
	}

	public String getInterPolicyOid() {
		return this.interPolicyOid;
	}

	public void setInterPolicyOid(String interPolicyOid) {
		this.interPolicyOid = interPolicyOid;
	}

	public void viewCandidate(ActionEvent actionEvent) {
		UIComponent component = actionEvent.getComponent();
		Map<String, Object> attributes = component.getAttributes();
		if (this.conversation.isTransient()) {
			this.conversation.begin();
		}
		this.selectedCA = (CertificateAuthorityEntity) attributes
				.get("selectedCA");
	}

	public void unselectCA(ActionEvent actionEvent) {
		this.conversation.end();
	}

	public void add(ActionEvent actionEvent) {
		LOG.debug("add certificate authority: " + this.name);
		LOG.debug("key size: " + this.keySize);
		LOG.debug("validity: " + this.validity);
		FacesContext facesContext = FacesContext.getCurrentInstance();
		try {
			this.certificateAuthorityManagerBean.addCertificateAuthority(
					this.name, this.subject, this.keySize, this.validity,
					this.policyOid, this.cps, this.crlValidity,
					this.crlOverlap, this.interSubject, this.interPolicyOid,
					this.interValidity, this.interSpawnInterval,
					this.interSpawnCount);
		} catch (ExistingCertificateAuthorityException e) {
			facesContext.addMessage("addDialogForm:name", new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "Existing CA", null));
			return;
		} catch (InvalidX500NameException e) {
			facesContext.addMessage("addDialogForm:subject", new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "Invalid subject.", null));
			return;
		} catch (InvalidPolicyException e) {
			facesContext.addMessage("addDialogForm:policyOid",
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Invalid OID.", null));
			return;
		}
		facesContext.addMessage(null, new FacesMessage(
				FacesMessage.SEVERITY_INFO, "Added CA " + this.name, null));
		RequestContext requestContext = RequestContext.getCurrentInstance();
		requestContext.addCallbackParam("caAdded", true);
		this.conversation.end();
		this.name = null;
		this.subject = null;
		this.policyOid = null;
		this.cps = null;
		this.interSubject = null;
	}

	public void prepareAdd(ActionEvent actionEvent) {
		LOG.debug("prepare add");
		if (this.conversation.isTransient()) {
			this.conversation.begin();
		}
	}

	public void removeCandidate(ActionEvent actionEvent) {
		UIComponent component = actionEvent.getComponent();
		Map<String, Object> attributes = component.getAttributes();
		if (this.conversation.isTransient()) {
			this.conversation.begin();
		}
		this.removeCandidate = (CertificateAuthorityEntity) attributes
				.get("selectedCA");
		LOG.debug("remove candidate: " + this.removeCandidate.getName());
	}

	public void removeCA(ActionEvent actionEvent) {
		LOG.debug("remove certificate authority: "
				+ this.removeCandidate.getName());
		this.certificateAuthorityManagerBean
				.removeCertificateAuthority(this.removeCandidate);
		FacesContext facesContext = FacesContext.getCurrentInstance();
		facesContext.addMessage(null, new FacesMessage(
				FacesMessage.SEVERITY_INFO, "Removed certificate authority "
						+ this.removeCandidate.getName(), null));
		this.removeCandidate = null;
		this.conversation.end();
	}
}
